/**
 * 
 */
package unifor.filetransfer.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import unifor.filetransfer.Principal;
import unifor.filetransfer.exception.SegmentoInvalido;


/**
 * @author landim
 * 
 */
public class RecepcaoUtil {

	   /**
     * Gerar o cabecalho do PDU de envio
     * @param segmento do pdu 
     * @param primeiro boolean indicando se esse foi o primeiro segmento recebido
     * @return
     * @throws SegmentoInvalido 
     */
    public static byte[] pegarNomeArquivo(byte[] segmento, boolean primeiro) throws SegmentoInvalido {
        byte[] result = null;
        
        if (segmento.length == 2 && primeiro) {
            //PDU de RESPOSTA
            
            if (segmento[1] == 1) {
                //TUDO OK
            	desconectar();
            } 
            if (segmento[1] == 2) {
                //ERRO!
                throw new SegmentoInvalido();
            }
            
        } 
        if (primeiro && segmento[0] == 1) {
            //Envio
            //Tamanho do cabecalho
            result = new byte[segmento[3]];
            System.arraycopy(segmento, 0, result, 0, result.length);
            
            
            
        }
        if (!primeiro && segmento[0] == 1) {
            //Envio
            //Tamanho do cabecalho
            result = new byte[segmento.length];
            System.arraycopy(segmento, 0, result, 0, segmento.length);
           
        }
        
        
        return result;
    }
    /**
     * Gerar o cabecalho do PDU de envio
     * @param segmento do pdu 
     * @param primeiro boolean indicando se esse foi o primeiro segmento recebido
     * @return
     * @throws SegmentoInvalido 
     */
    public static byte[] pegarCabecalho(byte[] segmento, boolean primeiro) throws SegmentoInvalido {
        byte[] result = null;
        
        if (segmento.length == 2 && primeiro) {
            //PDU de RESPOSTA
            
            if (segmento[1] == 1) {
            	result = segmento;
                //TUDO OK
            } 
            if (segmento[1] == 2) {
                //ERRO!
                throw new SegmentoInvalido();
            }
            
        } 
        if (primeiro && segmento[0] == 1) {
            //Envio
            //Tamanho do cabecalho
            result = new byte[segmento[3]];
            System.arraycopy(segmento, 0, result, 0, result.length);
            
            
            
        }
        
        return result;
    }
    
    /**
     * Gerar o cabecalho do PDU de envio
     * @param segmento do pdu 
     * @param primeiro boolean indicando se esse foi o primeiro segmento recebido
     * @return
     * @throws SegmentoInvalido 
     */
    public static CabecalhoPdu pegarCabecalhoPdu(byte[] segmento, boolean primeiro) throws SegmentoInvalido {
    	CabecalhoPdu result = new CabecalhoPdu();
        
        if (segmento.length == 2 && primeiro) {
            //PDU de RESPOSTA
            result.setType(CabecalhoPdu.RESPOSTA);
            if (segmento[1] == 1) {
                //TUDO OK
            	result.setStatus(CabecalhoPdu.TUDO_OK);
            } 
            if (segmento[1] == 2) {
                //ERRO!
            	result.setStatus(CabecalhoPdu.DEU_ERRO);
                throw new SegmentoInvalido();
            }
            
        } 
        if (primeiro && segmento[0] == 1) {
            //Envio
            //Tamanho do cabecalho
            
        	result.setType(CabecalhoPdu.ENVIO);
        	result.setCrc(ProtocoloUtil.toInt(new byte[]{segmento[1], segmento[2]}));
        	result.setTamanhoArquivo(ProtocoloUtil.toInt(new byte[]{segmento[4], segmento[5], segmento[6], segmento[7]}));
        	result.setTamanho(segmento[3]);
        	
        	String nomeArquivo = new String();
        	
			for (int i=8;i<segmento.length;i++) {
				nomeArquivo = nomeArquivo.concat(Character.toString((char) segmento[i]));
			}        	
        	result.setNomeArquivo(nomeArquivo);
            
            
        }
        
        return result;
    }
    /**
     * Gerar o cabecalho do PDU de envio
     * @param segmento do pdu 
     * @param primeiro boolean indicando se esse foi o primeiro segmento recebido
     * @return
     * @throws SegmentoInvalido 
     */
    public static byte[] pegarArquivoDoPdu(byte[] segmento, boolean primeiro) throws SegmentoInvalido {
        byte[] result = null;
        
        if (segmento.length == 2 && primeiro) {
            //PDU de RESPOSTA
            
            if (segmento[1] == 1) {
                //TUDO OK
            } 
            if (segmento[1] == 2) {
                //ERRO!
                throw new SegmentoInvalido();
            }
            
        } 
        if (primeiro && segmento[0] == 1) {
            //Envio
            //Tamanho do cabecalho
        	int tamanhoCabecalho = segmento[3];
        	result = new byte[segmento.length - tamanhoCabecalho];
        	System.arraycopy(segmento, tamanhoCabecalho, result, 0, result.length);
            
        }
        if (!primeiro) {
            //Envio
            //Tamanho do cabecalho
        	result = new byte[segmento.length];
        	System.arraycopy(segmento, 0, result, 0, result.length);
            
        }
        
        return result;
    }
    
    public static void desconectar() {
        try {
            Principal.clienteSocket.close();
            Principal.logTrans("Transmissao encerrada");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Principal.logTrans("Erro ao abrir conexao");
            Principal.logTrans(e.getMessage());
            
        }
        
    }
    
    /**
     *  Reads a file storing intermediate data into an array.
     *  @param file the file to be read
     *  @return a file data
     */
     public static  byte[] copyTo(String file, String dest) throws Exception {
         InputStream in = null;
         OutputStream outStream = null;
//        byte[] out             = new byte[0];

        try{
            in = new BufferedInputStream(new FileInputStream(file));
            outStream = new BufferedOutputStream(new FileOutputStream(dest));

           // the length of a buffer can vary
           int bufLen = 2000*1024;
           
           byte[] buf = new byte[bufLen];
           byte[] tmp = null;
           int len    = 0;
           int index = 0;
           
           while((len = in.read(buf,0,bufLen)) != -1){
              // extend array
//               tmp = new byte[out.length + len];
               tmp = new byte[len];

              // copy data
//              System.arraycopy(out,0,tmp,0,out.length);
//              System.arraycopy(buf,0,tmp,out.length,len);
//              out = tmp;
               System.out.println("copiando pacote " + index++);
               if (len < bufLen) {
                   tmp = new byte[len];
                   System.arraycopy(buf,0,tmp,0,len);
                   outStream.write(tmp);
               } else {
                   outStream.write(buf);
               }
               outStream.flush();
              tmp = null;        
              buf = new byte[bufLen];

           }

        } finally {
           // always close the stream
           if (in != null) {
               try{ 
                   in.close();
                   outStream.close();
               }catch (Exception e){
                   
               }
           }

        }
        return null;
     }   
    
}
